package main

import (
	"log"
	"time"
)

func EncodeUtcTime(t time.Time, b []byte) {
	if len(b) < 8 {
		log.Println("encodeUtcTime: no enough buffer size.")
	}
	nanoSec := t.UnixNano()
	timestamp := nanoSec / 1e9
	fraction := int((float64(nanoSec-timestamp*1e9) / 1e9) * 0x1000000)
	qflag := byte(0)
	for i := 0; i < 4; i++ {
		shift := 8 * uint(4-i-1)
		mask := int64(0xff) << shift
		b[i] = byte((timestamp & mask) >> shift)
	}
	for i := 0; i < 3; i++ {
		shift := 8 * uint(3-i-1)
		mask := int(0xff) << shift
		b[4+i] = byte((fraction & mask) >> shift)
	}
	b[7] = qflag
}

func DecodeUtcTime(b []byte) time.Time {
	if len(b) < 8 {
		log.Println("decodeUtcTime: no enough buffer size.")
	}
	timestamp := int64(0)
	for i := 0; i < 4; i++ {
		shift := 8 * uint(4-i-1)
		timestamp |= (int64(b[i]) << shift)
	}
	fraction := int(0)
	for i := 0; i < 3; i++ {
		shift := 8 * uint(3-i-1)
		fraction |= (int(b[4+i]) << shift)
	}
	//qflag := b[7]
	nanoSec := timestamp*1e9 + int64((float64(fraction)/0x1000000)*1e9)
	return time.Unix(0, nanoSec)
}

func EncodeUint(iVal uint32, b []byte) {
	b_len := len(b)
	if b_len > 4 {
		b_len = 4
	}
	for i := 0; i < b_len; i++ {
		shift := 8 * uint(b_len-i-1)
		mask := uint32(0xff) << shift
		b[i] = byte((iVal & mask) >> shift)
	}
}

func DecodeUint(b []byte) uint32 {
	iVal := uint32(0)
	b_len := len(b)
	if b_len > 4 {
		b_len = 4
	}
	for i := 0; i < b_len; i++ {
		shift := 8 * uint(b_len-i-1)
		iVal |= (uint32(b[i]) << shift)
	}
	return iVal
}

func EncodeInt(iVal int32, b []byte) {
	EncodeUint(uint32(iVal), b)
}

func DecodeInt(b []byte) int32 {
	return int32(DecodeUint(b))
}
